package educrypt.gui.components;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.swing.DefaultComboBoxModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JList;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionListener;

import educrypt.commons.Global;
import educrypt.gui.util.GuiUtil;
import educrypt.gui.view.EditorAlphabetView;
import educrypt.i18n.Messages;
import educrypt.resources.EduCryptResources;

class EditorAlphabetDialog extends EducryptDialog implements EditorAlphabetView {

	private final static int CBX_INDEX_GROUP_ALL = 0;
	private final static int CBX_INDEX_GROUP_NOPLAYFAIR = 1;
	private final static int CBX_INDEX_GROUP_PLAYFAIR = 2;

	private static final long serialVersionUID = -3355116875536110892L;

	private final JLayeredPane contentPanel = new JLayeredPane();
	private JTextField tfAlphabetName;
	private JTextArea txtAlphabetSymbols;
	private JComboBox cbxCipherGroup;
	private JList lstStoredAlphabets;
	private JButton btnAddAlphabet, btnRemoveAlphabet, btnValidate,
			btnRemoveNewAlphabetName, btnRemoveNewAlphabetSymbols;

	public EditorAlphabetDialog(Window owner) {
		super(owner);
		this.setSize(500, 450);
		this.setPreferredSize(this.getSize());
		setTitle(Messages.getString("guiAlphabetEditor"));

		getContentPane().setLayout(new BorderLayout());
		contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
		getContentPane().add(contentPanel, BorderLayout.CENTER);
		contentPanel.setLayout(null);

		JLabel lblAlphabetEditor = new JLabel(
				Messages.getString("guiAlphabetEditor"));
		lblAlphabetEditor.setFont(new Font("Tahoma", Font.BOLD, 15));
		lblAlphabetEditor.setBounds(21, 11, 378, 24);
		contentPanel.add(lblAlphabetEditor);

		JLabel lblCipherGroup = new JLabel(Messages.getString("guiCipherGroup"));
		lblCipherGroup.setBounds(21, 49, 139, 14);
		contentPanel.add(lblCipherGroup);

		cbxCipherGroup = new JComboBox();
		cbxCipherGroup.setBounds(170, 46, 285, 20);
		contentPanel.add(cbxCipherGroup);

		JLabel lblAlphabetSymbols = new JLabel(
				Messages.getString("guiAlphabetSymbols"));
		lblAlphabetSymbols.setBounds(21, 112, 137, 14);
		contentPanel.add(lblAlphabetSymbols);

		ImageIcon iconAdd = new ImageIcon(
				EduCryptResources.getImageURL("plus24.png"));
		ImageIcon iconValidate = new ImageIcon(
				EduCryptResources.getImageURL("validate24.png"));
		ImageIcon iconRemove = new ImageIcon(
				EduCryptResources.getImageURL("remove24color.png"));

		btnValidate = new JButton(iconValidate);
		btnValidate.setBounds(460, 106, 24, 24);
		contentPanel.add(btnValidate);

		btnAddAlphabet = new JButton(iconAdd);
		btnAddAlphabet.setEnabled(false);
		btnAddAlphabet.setBounds(460, 134, 24, 24);
		contentPanel.add(btnAddAlphabet);

		btnRemoveAlphabet = new JButton(iconRemove);
		btnRemoveAlphabet.setBounds(460, 220, 24, 24);
		contentPanel.add(btnRemoveAlphabet);

		JLabel lblStoredAlphabets = new JLabel(
				Messages.getString("guiStoredAlphabets"));
		lblStoredAlphabets.setBounds(21, 216, 139, 28);
		contentPanel.add(lblStoredAlphabets);

		JLabel lblAlphabetName = new JLabel(
				Messages.getString("guiAlphabetName"));
		lblAlphabetName.setBounds(21, 80, 137, 14);
		contentPanel.add(lblAlphabetName);

		tfAlphabetName = new JTextField();
		tfAlphabetName.setColumns(10);
		tfAlphabetName.setBounds(168, 76, 287, 24);
		contentPanel.add(tfAlphabetName);

		initializeSymbolsTextArea();
		initializeAlphabetList();
		initializeTransparentButtons();

		showCiphersGroup();
	}

	private void initializeSymbolsTextArea() {
		final int OFFSET = 24;

		JScrollPane scrollPaneSymbols = new JScrollPane((Component) null);
		scrollPaneSymbols.setBounds(168, 106, 287, 99);
		contentPanel.add(scrollPaneSymbols);

		txtAlphabetSymbols = new JTextArea();
		txtAlphabetSymbols.setLineWrap(true);
		txtAlphabetSymbols.setMargin(new Insets(0, 0, 0, OFFSET));
		scrollPaneSymbols.setViewportView(txtAlphabetSymbols);

		final JScrollBar verticalBar = scrollPaneSymbols.getVerticalScrollBar();
		verticalBar.setBorder(new EmptyBorder(OFFSET, 0, 0, 0));
		verticalBar.setPreferredSize(new Dimension(OFFSET, verticalBar
				.getHeight()));

		verticalBar.addComponentListener(new ComponentListener() {
			@Override
			public void componentShown(ComponentEvent arg0) {
				txtAlphabetSymbols.setMargin(new Insets(0, 0, 0, 0));
				txtAlphabetSymbols.repaint();
			}

			@Override
			public void componentResized(ComponentEvent arg0) {
			}

			@Override
			public void componentMoved(ComponentEvent arg0) {
			}

			@Override
			public void componentHidden(ComponentEvent arg0) {
				txtAlphabetSymbols.setMargin(new Insets(0, 0, 0, OFFSET));
				txtAlphabetSymbols.repaint();
			}
		});
	}

	private void initializeAlphabetList() {
		JScrollPane scrollPane = new JScrollPane((Component) null);
		scrollPane.setBounds(170, 216, 285, 195);
		contentPanel.add(scrollPane);

		lstStoredAlphabets = new JList();
		scrollPane.setViewportView(lstStoredAlphabets);
	}

	private void initializeTransparentButtons() {
		ImageIcon iconClearBW = new ImageIcon(
				EduCryptResources.getImageURL("clear16.png"));
		// btnRemoveNewAlphabetName
		btnRemoveNewAlphabetName = new JButton(iconClearBW);
		btnRemoveNewAlphabetName.setBounds(430, 76, 24, 24);

		btnRemoveNewAlphabetName.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				tfAlphabetName.setText("");
			}
		});
		GuiUtil.setTransparentButtonBackground(btnRemoveNewAlphabetName);
		contentPanel.add(btnRemoveNewAlphabetName, 1, -1);
		// btnRemoveNewAlphabetSymbol
		btnRemoveNewAlphabetSymbols = new JButton(iconClearBW);
		btnRemoveNewAlphabetSymbols.setBounds(430, 106, 24, 24);

		btnRemoveNewAlphabetSymbols.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				txtAlphabetSymbols.setText("");
			}
		});
		GuiUtil.setTransparentButtonBackground(btnRemoveNewAlphabetSymbols);
		contentPanel.add(btnRemoveNewAlphabetSymbols, 1, -1);
	}

	@Override
	public void addListener(ActionListener ctr) {
		cbxCipherGroup.setActionCommand(CIPHER_SELECTED);
		cbxCipherGroup.addActionListener(ctr);

		btnValidate.setActionCommand(VALIDATE_ALPHABET);
		btnValidate.addActionListener(ctr);

		btnAddAlphabet.setActionCommand(ADD_ALPHABET);
		btnAddAlphabet.addActionListener(ctr);

		btnRemoveAlphabet.setActionCommand(REMOVE_ALPHABET);
		btnRemoveAlphabet.addActionListener(ctr);

		lstStoredAlphabets
				.addListSelectionListener((ListSelectionListener) ctr);

		txtAlphabetSymbols.getDocument().addDocumentListener(
				new DocumentListener() {

					@Override
					public void removeUpdate(DocumentEvent arg0) {
						btnAddAlphabet.setEnabled(false);

					}

					@Override
					public void insertUpdate(DocumentEvent arg0) {
						btnAddAlphabet.setEnabled(false);

					}

					@Override
					public void changedUpdate(DocumentEvent arg0) {
						btnAddAlphabet.setEnabled(false);

					}
				});
	}

	@Override
	public void showCiphersGroup() {
		cbxCipherGroup.setEnabled(true);

		String[] ciphers = new String[] {
				Messages.getString("guiCiphersGroupAll"),
				Messages.getString("guiCiphersGroupNotPlayfair"),
				Messages.getString("guiCiphersGroupPlayfair") };
		cbxCipherGroup.setModel(new DefaultComboBoxModel(ciphers));
	}

	@Override
	public void setSelectedCipherGroup(int cipher) {
		switch (cipher) {
		case Global.CAESAR:
		case Global.VIGENERE:
		case Global.HILL:
			cbxCipherGroup.setSelectedIndex(CBX_INDEX_GROUP_NOPLAYFAIR);
			break;
		case Global.PLAYFAIR:
			cbxCipherGroup.setSelectedIndex(CBX_INDEX_GROUP_PLAYFAIR);
			break;
		default:
			cbxCipherGroup.setSelectedIndex(CBX_INDEX_GROUP_ALL);
		}
	}

	@Override
	public List<Integer> getSelectedCiphers() {
		List<Integer> selectedCiphers = new ArrayList<Integer>();

		if (cbxCipherGroup.getSelectedIndex() == CBX_INDEX_GROUP_ALL) {
			selectedCiphers = Arrays.asList(new Integer[] { Global.CAESAR,
					Global.VIGENERE, Global.PLAYFAIR, Global.HILL });

		} else if (cbxCipherGroup.getSelectedIndex() == CBX_INDEX_GROUP_NOPLAYFAIR) {
			selectedCiphers = Arrays.asList(new Integer[] { Global.CAESAR,
					Global.VIGENERE, Global.HILL });

		} else if (cbxCipherGroup.getSelectedIndex() == CBX_INDEX_GROUP_PLAYFAIR) {
			selectedCiphers = Arrays.asList(new Integer[] { Global.PLAYFAIR });
		}
		return selectedCiphers;
	}

	@Override
	public void setAlphabetToEdit(String name, String symbols) {
		this.tfAlphabetName.setText(name);
		this.txtAlphabetSymbols.setText(symbols);
	}

	@Override
	public void setAlphabetNameToEdit(String name) {
		this.tfAlphabetName.setText(name);
	}

	@Override
	public void setAlphabetSymbolsToEdit(String symbols) {
		this.txtAlphabetSymbols.setText(symbols);
	}

	@Override
	public String getAlphabetNameToEdit() {
		return tfAlphabetName.getText();
	}

	@Override
	public String getAlphabetSymbolsToEdit() {
		return txtAlphabetSymbols.getText();
	}

	@Override
	public void showAlphabets(List<String> alphabets) {
		lstStoredAlphabets.setListData(alphabets.toArray());
	}

	@Override
	public String getSelectedAlphabet() {
		Object selectedValue = lstStoredAlphabets.getSelectedValue();
		String selectedAlphabet = (selectedValue != null) ? selectedValue
				.toString() : "";
		return selectedAlphabet;
	}

	@Override
	public int getSelectedAlphabetIndex() {
		return lstStoredAlphabets.getSelectedIndex();
	}

	@Override
	public void enableAddButton(boolean show) {
		btnAddAlphabet.setEnabled(show);
	}
}
